import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;

public class GUI extends JPanel {

	private JPanel mainPanel;
	private JPanel leftPanel;
	private JPanel centerPanel;
	private JPanel bottomPanel;
	private JPanel nameBar;
	private JPanel leftMenu;

	private JLabel nameTime;

	//initialize colors to be used
	final static Color newTeal = new Color(0, 153, 153);
	final static Color newYellow = new Color(255, 204, 0);
	final static Color newBlue = new Color(4, 40, 220);

	//the maximum number of rows of tables in the restaurant
	private final static int maxRow = 4;

	//the maximum number of columns of tables in the restaurant
	private final static int maxCol = 4;

	//the lowest table number to found at the restaurant
	private final static int lowTable = 11;


	//The size of border thickness throughout the program
	private final static int borderSize = 75;

	//Used to determine if a server has a section
	public static ArrayList<Integer> section;
	static ArrayList<Integer> blueSection;
	static ArrayList<Integer> redSection;
	static ArrayList<Integer> yellowSection;
	static ArrayList<Integer> whiteSection;
	static ArrayList<Integer> graySection;

	private static boolean sectionButtonClicked;
	
	private static int tableNumber;

	int xSize;
	int ySize;

	private static int userID;
	private static int userJobCode;
	private static String userName;

	/**
	 * Constructor for the GUI object. Takes an ID and job code as input and
	 * creates the proper layout for each job role.
	 * 
	 * @param id
	 *            The id of the current user.
	 * @param jobCode
	 *            The job code of the current user. 0 = Hostess, 1 = Server, 2 =
	 *            Manager
	 * @param name
	 *            The last name of the current user.
	 * @param ai
	 * 			  The ArrayList<Integer> of the server's section (may be null if no section declared)
	 */
	public GUI(int id, int jobCode, String name) {
		//set initial variables
		userID = id;
		userJobCode = jobCode;
		userName = name;
		
		//Determines if there is already a setup for server section
		ArrayList<Integer> serverSection = OrderWindow.getSection();
		if(serverSection == null){
			section = new ArrayList<Integer>();
		}
		else{
			section = serverSection;
		}

		//call methods to set up GUI
		setWindowSize();
		initializePanels();	

		buildBottomPanel();
		buildLeftPanel(userJobCode);
		buildCenterPanel(userJobCode);

		mainPanel.add(bottomPanel, BorderLayout.PAGE_END);
		mainPanel.add(leftPanel, BorderLayout.LINE_START);
		mainPanel.add(centerPanel, BorderLayout.CENTER);

		add(mainPanel);
	}//End constructor


	/**
	 * Builds the center panel to display the restaurant floor
	 * @param jc - the user Job Code (0 = hostess, 1 = server, 2 = manager)
	 */
	private void buildCenterPanel(int jc) {
		createSections();

		if (jc != 1){
			buildTables();
		}
		else{
			buildServerTables();
		}

	}//End buildCenterPanel method



	/**
	 * Create the table sections for the hostess and manager view
	 */
	private void createSections() {
		blueSection = new ArrayList<Integer>();
		blueSection.add(31);
		blueSection.add(41);
		blueSection.add(42);

		redSection = new ArrayList<Integer>();
		redSection.add(11);
		redSection.add(21);
		redSection.add(12);

		yellowSection = new ArrayList<Integer>();
		yellowSection.add(22);
		yellowSection.add(32);
		yellowSection.add(23);
		yellowSection.add(33);

		whiteSection = new ArrayList<Integer>();
		whiteSection.add(13);
		whiteSection.add(14);
		whiteSection.add(24);

		graySection = new ArrayList<Integer>();
		graySection.add(43);
		graySection.add(34);
		graySection.add(44);

	}//End createSections method


	/**
	 * Builds a 4X4 visual representation of the restaurant floor for server
	 */
	private void buildServerTables() {

		for(int i = 1; i <= maxRow; i++){
			for(int j = 1 ;j <= maxCol; j++){
				Integer table=j*10+i;
				if(containsTable(table,section))
					centerPanel.add(newTable(table, newBlue, Color.white));
				else
					centerPanel.add(newTable(table, newYellow, Color.black));
			}
		}//End for loop

	}//End buildServerTables method


	/**
	 * Builds a 4X4 visual representation of the restaurant floor for hostess and manager
	 */
	private void buildTables() {

		for(int i = 1; i <= maxRow; i++){
			for(int j = 1; j <= maxCol; j++){
				Integer table=j*10+i; //10 is used - could be anything
				if(containsTable(table,blueSection))
					centerPanel.add(newTable(table, newBlue, Color.black));
				else
					if(containsTable(table, redSection))
						centerPanel.add(newTable(table, Color.RED, Color.black));
					else if(containsTable(table, yellowSection))
						centerPanel.add(newTable(table, newYellow, Color.black));
					else if(containsTable(table, whiteSection))
						centerPanel.add(newTable(table, Color.WHITE, Color.black));
					else
						centerPanel.add(newTable(table, Color.GRAY, Color.black));
			}
		}//End for loop

	}//End buildTables method


	/**
	 * Builds the visual representation of a square table on the restaurant floor
	 * @param tableNum - the table number
	 * @param color - the color of the section
	 * @param text - the color of the text of the table number
	 * @return JButton table - the completed square table to be displayed
	 */
	private JButton newTable(Integer tableNum, Color color, Color text){

		String tableString = Integer.toString(tableNum);
		JButton table = new JButton(tableString);
		table.setBackground(color);
		table.setForeground(text);
		Border thickBorder=new LineBorder(newTeal, borderSize);
		table.setBorder(thickBorder);
		table.setFont(new Font("Arial", Font.PLAIN, 40));
		table.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				if(userJobCode != 1){//if user is not a server
					table.setText(HostessAtTable(tableNum));
				}
				else{//if user is a server
					if(sectionButtonClicked == false){
						if (containsTable(Integer.parseInt(table.getText()), section) == true){
							int customers = PopUp.getNumCustomers();
							if (customers > -1){
								//tableSquare is the button clicked
								//tableNumber is passed to the database to obtain the table number
								JButton tableSquare = (JButton)e.getSource();
								setTableNumber(tableSquare);
								newOrderWindow(customers);
							}
						}
						else{
							boolean myTable=PopUp.takeTable();
							if(!myTable){
								return;
							}
							else{
								section.add(tableNum);
								table.setBackground(newBlue);
								table.setForeground(Color.white);
								int customers = PopUp.getNumCustomers();
								if (customers > -1){
									//tableSquare is the button clicked
									//tableNumber is passed to the database to obtain the table number
									JButton tableSquare = (JButton)e.getSource();
									setTableNumber(tableSquare);
									newOrderWindow(customers);
								}
								else{
									section.remove(section.size()-1);
									table.setBackground(newYellow);
									table.setForeground(Color.BLACK);
								}
							}
						}
					}
					else{//if sectionButtonClicked == true
						if(table.getBackground() == newYellow){
						section.add(tableNum);
						table.setBackground(newBlue);
						table.setForeground(Color.white);
						}
						else{//remove the table from the section
							for(int i = 0; i < section.size(); i++){
								if(Integer.parseInt(table.getText()) == section.get(i)){
									table.setBackground(newYellow);
									table.setForeground(Color.BLACK);
									section.remove(i);
									break;
								}
							}
						}
					}
				}//End of outer if/else

			}//End ActionEvent listener

		});
		return table;
	}//End newTable method

	
	/**
	 * Calls to the PopUp Class to runHostessTable method
	 * @param tableNum - the table that was selected
	 * @return the date or the same table number
	 */
	private static String HostessAtTable(Integer tableNum) {
		String selection=PopUp.hostessTable(tableNum);
		return selection;
	}//End HostessAtTable method


	/**
	 * Identifies whether a given table is in a given section
	 * @param table - the table number
	 * @param section2 - the section number which will be searched to see if the table number can be found
	 * @return boolean - whether the table number is found in the section array or not
	 */
	static boolean containsTable(Integer table, ArrayList<Integer> section2) {
		if(section2==null)
			return false;
		for(int i = 0;i < section2.size(); i++){
			if(table==section2.get(i))
				return true;
		}
		return false;
	}//End contains method


	/**
	 * Builds the leftPanel which consists of the user's name/date and the menu choices depending on job code
	 * @param jc - the user Job Code (0 = hostess, 1 = server, 2 = manager)
	 */
	private void buildLeftPanel(int jc) {
		buildNameBar();
		buildMenu(jc);

		leftPanel.add(nameBar, BorderLayout.PAGE_START);
		leftPanel.add(leftMenu);
	}//End buildLeftPanel method


	/**
	 * Builds the list of menu items to be placed on the leftMenu
	 * @param jc - the user Job Code (0 = hostess, 1 = server, 2 = manager)
	 */
	private void buildMenu(int jc) {
		leftMenu = new JPanel();
		leftMenu.setLayout(new GridLayout(3, 3));

		if(jc == 0){
			createHostessButtons();
		}
		if(jc == 1){
			createServerButtons();
		}
		if(jc == 2){
			createManagerButtons();
		}
		leftMenu.setSize(500, 500);
	}//End buildMenu method


	/**
	 * Create the menu buttons for the main server screen - to be added to the leftPanel
	 */
	private void createManagerButtons() {
		JButton reservationsM = new JButton ("Reservations");
		reservationsM.setFont(new Font("Arial", Font.PLAIN, 40));
		reservationsM.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				GridsWindow.setManagerSelection(1);
				GridsWindow.setButtonNameText("Reservations");
				newGridsWindow();

			}
		});//End ActionListener

		JButton employees = new JButton ("Employees");
		employees.setFont(new Font("Arial", Font.PLAIN, 40));
		employees.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				GridsWindow.setManagerSelection(2);
				GridsWindow.setButtonNameText("Employees");
				newGridsWindow();
			}
		});//End ActionListener

		JButton menuItems = new JButton ("Menu Items");
		menuItems.setFont(new Font("Arial", Font.PLAIN, 40));
		menuItems.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				GridsWindow.setManagerSelection(3);
				GridsWindow.setButtonNameText("Menu Items");
				newGridsWindow();
			}
		});//End ActionListener

		leftMenu.add(reservationsM);
		leftMenu.add(employees);
		leftMenu.add(menuItems);
	}//End createManagerButtons method


	/**
	 * Create the menu buttons for the main server screen - to be added to the leftPanel
	 */
	private void createServerButtons() {

		JButton setSections = new JButton ("Set Sections");
		setSections.setFont(new Font("Arial", Font.PLAIN, 40));
		setSections.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				JButton jb = (JButton)e.getSource();
				if (jb.getBackground()!= Color.DARK_GRAY) {
					jb.setBackground(Color.DARK_GRAY);
					sectionButtonClicked = true;
				}
				else{
					sectionButtonClicked = false;
					jb.setBackground(new JButton().getBackground());
					centerPanel.revalidate();
					centerPanel.repaint();
				}
			}
		});//End ActionListener

		JButton takeOutS = new JButton ("Take Out");
		takeOutS.setFont(new Font("Arial", Font.PLAIN, 40));
		takeOutS.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				int customers = PopUp.getNumCustomers();
				if (customers > -1) {
					setSectionButtonClicked(false);
					newOrderWindow(customers);
				}
			}
		});//End ActionListener

		JButton blank = new JButton ("");
		blank.setFont(new Font("Arial", Font.PLAIN, 40));
		blank.setEnabled(false);


		leftMenu.add(setSections);
		leftMenu.add(takeOutS);
		leftMenu.add(blank);
	}//End createServerButtons method


	/**
	 * Create the menu buttons for the main hostess screen - to be added to the leftPanel
	 */
	private void createHostessButtons() {
		JButton reservations = new JButton ("Reservations");
		reservations.setFont(new Font("Arial", Font.PLAIN, 40));
		reservations.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				GridsWindow.setButtonNameText("Reservations");
				newGridsWindow();
			}
		});//End ActionListener

		JButton waitList = new JButton ("Wait List");
		waitList.setFont(new Font("Arial", Font.PLAIN, 40));
		waitList.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				GridsWindow.setButtonNameText("WaitList");
				newGridsWindow();
			}
		});//End ActionListener

		JButton takeOutH = new JButton ("Take Out");
		takeOutH.setFont(new Font("Arial", Font.PLAIN, 40));
		takeOutH.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				int customers = PopUp.getNumCustomers();
				if (customers > -1) {
					newOrderWindow(customers);
				}
			}
		});//End ActionListener

		leftMenu.add(reservations);
		leftMenu.add(waitList);
		leftMenu.add(takeOutH);

	}//End createHostessButtons method


	/**
	 * Builds a Panel that displays the username and time
	 */
	private void buildNameBar() {
		nameBar = new JPanel();
		nameBar.setLayout(new GridLayout(1, 1));
		nameBar.setPreferredSize(new Dimension(500, 150));
		nameBar.setMinimumSize(new Dimension(500, 150));

		nameTime = buildNameTime(userName, new Date());
		nameBar.add(nameTime);	
		leftPanel.add(nameBar);
	}//End buildNameBar method


	/**
	 * Create a button that displays the user's name and time
	 * @param name - the user's name
	 * @param time - the current time
	 * @return JButton - the button (unselectable) that contains the user's name and time
	 */
	private JLabel buildNameTime(String name, Date time) {
		JLabel userInfo = new JLabel();
		userInfo.setHorizontalAlignment(SwingConstants.CENTER);
		DateFormat dateFormat = new SimpleDateFormat("HH:mm");
		userInfo.setText("<html>" + name + "<br />" + dateFormat.format(time)
				+ "</html>");
		userInfo.setFont(new Font("Arial", Font.PLAIN, 40));

		return userInfo;
	}//End buildNameTime method


	/**
	 * Creates a panel to be displayed at the bottom of mainPanel.  The clock out button allows the user to clock out.
	 */
	private void buildBottomPanel() {
		JPanel exitPanel = new JPanel();
		exitPanel.setLayout(new FlowLayout());
		exitPanel.setBackground(newTeal);

		JButton exitButton = new JButton("Exit");
		exitButton.setFont(new Font("Arial", Font.PLAIN, 40));
		exitButton.setPreferredSize(new Dimension(600, 75));
		exitButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				newLogInWindow();
			}
		});//End ActionListener

		exitPanel.add(exitButton);

		JButton clockOut = new JButton("Clock Out");
		clockOut.setFont(new Font("Arial", Font.PLAIN, 40));
		clockOut.setPreferredSize(new Dimension(600, 75));
		clockOut.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				runEndSession();
			}
		});//End ActionListener

		exitPanel.add(exitButton);
		exitPanel.add(clockOut);
		bottomPanel.add(exitPanel);		
	}//End buildBottomPanel method


	/**
	 * Runs the runClockOut methods depending on job code
	 */
	private void runEndSession() {
		if (userJobCode == 1) {//if the user is a server
			// tipAmount obtains the cash tip amount being claimed
			// 0.00 if no cash tips were claimed
			// empty string if user cancels
			String tipAmount = PopUp.runServerClockOut();
			while (tipAmount.equals("CLEAR")) { // User clears the cash
				// tips display
				tipAmount = PopUp.runServerClockOut();
			}
			if (tipAmount.equals("")) {
				// do nothing - user cancelled
			} else {
				newLogInWindow();
			}
		} else {//if the user is not a server
			// if out = 0 then employee has clocked out.
			// if out = 1 then employee selected cancel and is still
			// clocked in
			int out = PopUp.runClockOut();
			if (out == 0) {
				newLogInWindow();
			} else {
				// do nothing
			}
		}
	}// End runClockOut method


	/**
	 * Initializes the panels to be placed on Main Panel
	 */
	private void initializePanels() {
		leftPanel = new JPanel();
		leftPanel.setLayout(new BorderLayout());

		centerPanel = new JPanel();
		centerPanel.setLayout(new GridLayout(4, 4));
		centerPanel.setBackground(newTeal);

		bottomPanel = new JPanel();	
		bottomPanel.setLayout(new FlowLayout());
		bottomPanel.setBackground(newTeal);
	}//End initializePanels method


	/**
	 * Sets up the size of the window to take up the entire screen.  Main Panel is the container for the reminder of the class.
	 */
	private void setWindowSize() {
		Toolkit tk = Toolkit.getDefaultToolkit();
		xSize = ((int) tk.getScreenSize().getWidth());
		ySize = ((int) tk.getScreenSize().getHeight());

		//Establish full screen size
		mainPanel = new JPanel();
		mainPanel.setPreferredSize(new Dimension(xSize, ySize));
		mainPanel.setLayout(new BorderLayout());
	}//End setWindowSize method

	/**
	 * Determines if the user can set a section or not
	 * @param b
	 */
	private void setSectionButtonClicked(boolean b) {
		sectionButtonClicked = b;
	}//End setSectionButtonClicked
	
	/**
	 * Sets the number of the table that was clicked from the restaurant floor for creating an order
	 * @param tableSquare - the JButton that was clicked
	 */
	private void setTableNumber(JButton tableSquare) {
		tableNumber = Integer.parseInt(tableSquare.getText());
	}//End setTableNumber method
	
	/**
	 * Obtains the table number that has been clicked for creating an order
	 * @return - the table number
	 */
	public static int getTableNumber(){
		return tableNumber;
	}//End getTableNumber method


	/**
	 * Creates a new instance of the LogIn Class, removes the current mainPanel and replaces it with start (LogIn Class)
	 * and then validates and repaints the screen
	 */
	public void newLogInWindow(){
		LogIn start = new LogIn();
		StartSystem.switchPanel(start);
	}// End newLogInWindow method


	/**
	 * Creates a new instance of the GUI Class, removes the current mainPanel and replaces it with gui (GUI Class)
	 * and then validates and repaints the screen
	 */
	public void newGUIWindow(){
		section.clear();
		GUI gui = new GUI(userID, userJobCode, userName);
		StartSystem.switchPanel(gui);
	}// End newLogInWindow method

	/**
	 * Creates a new instance of the OrderWindow Class, removes the current mainPanel and replaces it with oWindow (OrderWindow Class)
	 * and then validates and repaints the screen
	 */
	public void newOrderWindow(int c){
		OrderWindow oWindow = new OrderWindow(userID, userJobCode, userName, c);
		OrderWindow.setSections(section);
		StartSystem.switchPanel(oWindow);
	}// End newOrderWindow method

	/**
	 * Creates a new instance of the GridsWindow Class, removes the current mainPanel and replaces it with gWindow (GridsWindow Class)
	 * and then validates and repaints the screen
	 */
	public void newGridsWindow(){
		GridsWindow gWindow = new GridsWindow(userID, userJobCode, userName);
		StartSystem.switchPanel(gWindow);
	}// End newGridsWindow method



}//End of Class
